<?php
define('MY_SESS_TIME', 3600);   //SESSION 生存时长
//类定义
class My_Sess
{
    static public function init()
    {
        $domain = '.localhost.com';
        //不使用 GET/POST 变量方式
        ini_set('session.use_trans_sid',    0);
        //设置垃圾回收最大生存时间
        ini_set('session.gc_maxlifetime',   MY_SESS_TIME);
        //使用 COOKIE 保存 SESSION ID 的方式
        ini_set('session.use_cookies',      1);
        ini_set('session.cookie_path',      '/');
        //多主机共享保存 SESSION ID 的 COOKIE
        ini_set('session.cookie_domain',    $domain);
        //将 session.save_handler 设置为 user，而不是默认的 files
        session_module_name('user');
        //定义 SESSION 各项操作所对应的方法名：
        session_set_save_handler(
            array('My_Sess', 'open'),   //对应于静态方法 My_Sess::open()，下同。
            array('My_Sess', 'close'),
            array('My_Sess', 'read'),
            array('My_Sess', 'write'),
            array('My_Sess', 'destroy'),
            array('My_Sess', 'gc')
        );
    }   //end function
    static public function open($save_path, $session_name) {
        return true;
    }   //end function
    static public function close() {

        DB::getInstance()->close();
        return true;
    }   //end function

    static public function read($sesskey) {
        $data = DB::getInstance()->getField('sess', [
            'sesskey'   => $sesskey,
            'expiry'    => [
                '>=',
                time()
            ]
        ], 'data');

        DB::getInstance()->close();
        return $data;
    }   //end function

    static public function write($sesskey, $data) {
        $expiry = time() + MY_SESS_TIME;    //设置过期时间

        $sql = "insert into 
                            sess (sesskey, expiry, data)
                values 
                      ('{$sesskey}', '{$expiry}', '{$data}')";
        //写入 SESSION
        DB::getInstance()->query($sql);
        return true;
    }   //end function

    static public function destroy($sesskey) {

        $sql = "DELETE FROM sess WHERE sesskey='{$sesskey}'" ;
        DB::getInstance()->query($sql);
        return true;
    }   //end function

    static public function gc($maxlifetime = null) {

        $sql = 'DELETE FROM sess WHERE expiry<' . time();
        DB::getInstance()->query($sql);
        //由于经常性的对表 sess 做删除操作，容易产生碎片，
        //所以在垃圾回收中对该表进行优化操作。
        $sql = 'OPTIMIZE TABLE sess';
        DB::getInstance()->query($sql);
        return true;
    }   //end function
}   ///:~

class DB {
    private static $mysql = null;
    private function __construct()
    {

    }
    static public function getInstance()
    {
        if (empty(self::$mysql))
        {
            self::$mysql = new MysqliAdmin([
                'ip'        => '127.0.0.1',
                'user'      => 'root',
                'password'  => '123456',
                'database'  => 'test_session'
            ]);
        }
        return self::$mysql;
    }
}

class MysqliAdmin {
    private $ip;
    private $user;
    private $password;
    private $database;
    private $mysql;
    private $isClose = false;
    public function __construct($config)
    {
        $this->setConfig($config);
        $this->setInstance();
    }
    public function close()
    {
        if (!empty($this->isClose))
        {
            $this->isClose = true;
            $this->mysql->close();
        }
    }
    public function setConfig($config)
    {
        $chkArr     = ['ip', 'user', 'password', 'database'];
        $chkResult  = array_diff($chkArr, array_keys($config));
        //检查必传参数
        if (!empty($chkResult)) {
            die ('MysqliAdmin.config lack of params: '. implode(',', $chkResult));
        }
        $this->ip           = $config['ip'];
        $this->user         = $config['user'];
        $this->password     = $config['password'];
        $this->database     = $config['database'];
    }
    public function setInstance()
    {
        if ($this->isClose || empty($this->mysql))
        {
            $this->mysql = new mysqli();
            $this->mysql->connect($this->ip, $this->user, $this->password, $this->database);
        }
    }

    public function query($sql)
    {
        $this->setInstance();
        $res = $this->mysql->query($sql);
        return $res;
    }

    public function getOne($table, $where, $field = '*')
    {
        $sql = $this->getSelectSql($table, [$field])." where ".$this->getWhereSql($where);
        $result = $this->query($sql);
        if ($result)
        {
            $data   = $result->fetch_all(MYSQLI_ASSOC);
            $data   = isset($data[0]) ? $data[0] : false;
        } else {
            $data = null;
        }

        return $data;
    }

    public function getField($table, $where, $field)
    {
        $data = $this->getOne($table, $where, $field);
        return isset($data[$field]) ? $data[$field] : "";
    }

    public function delete($table, $where)
    {
        $this->setInstance();
        $findWhere = '';

        if (is_array($where))
        {
            $findWhere = $this->getWhereSql($where);
        } elseif (is_int($where))
        {
            $findWhere = 'id = '.$where;
        }
        $result = false;
        if (!empty($findWhere))
        {
            $result = $this->query('delete from '.$table." where ".$findWhere);
        }
        return $result;
    }

    public function find($table, $where, $idKey = 'id')
    {
        $findWhere = '';

        if (is_array($where))
        {
            $findWhere = $this->getWhereSql($where);
        } elseif (is_int($where))
        {
            $findWhere = $this->getWhereSql(["$idKey" => $where]);
        }
        $result = false;
        if (!empty($findWhere))
        {
            $result = $this->getOne($table, $where);
        }
        return $result;
    }

    private function getWhereSql($where) {
        if (!is_array($where))
        {
            return $where;
        }
        $whereArr = [];
        foreach ($where as $key => $value)
        {
            if (is_array($value) && count($value) == 2)
            {
                $whereArr[] = "{$key} {$value[0]} '$value[1]'";
            } else {
                $whereArr[] = "{$key} = '{$value}'";
            }
        }
        $findWhere = implode(' and ', $whereArr);
        return $findWhere;
    }

    private function getSelectSql($table, $fields)
    {
        $fields = implode(',', $fields);
        return "select {$fields} from {$table} ";
    }

}

 //初始化 SESSION 设置，必须在 session_start() 之前运行！！
 My_Sess::init();
session_start();

//$_SESSION['baba'] = '叫爸爸';
$_SESSION['baba'] = null;
echo $_SESSION['baba'];
//$mysqli = DB::getInstance();
//$sql = "DELETE FROM sess WHERE sesskey='m6hrj7lur8uf02vv79h3bk63ov'" ;
//$mysqli->query($sql);
 ?>